package com.greatwall.hip.cms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.NumberUtil;
import com.google.common.collect.Lists;
import com.greatwall.hip.cms.constant.Constant;
import com.greatwall.hip.cms.dao.LyFkybqkDao;
import com.greatwall.hip.cms.entity.LyFkybqk;
import com.greatwall.hip.cms.model.Req;
import com.greatwall.hip.cms.service.LyFkybqkService;
import com.greatwall.hip.cms.vo.DeptIndicatorAnalyseVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import static com.greatwall.hip.cms.constant.Constant.YEAR_DATE_PATTERN;

/**
 * 分科医保指标(LyFkybqk)表服务实现类
 *
 * @author makejava
 * @since 2021-07-05 16:05:03
 */
@Service("lyFkybqkService")
public class LyFkybqkServiceImpl implements LyFkybqkService {


    @Resource
    private LyFkybqkDao lyFkybqkDao;

    @Override
    public DeptIndicatorAnalyseVO queryDeptIndicatorAnalyse(Req req) {
        String date = req.getStartDate();

        String lastDate;

        List<DeptIndicatorAnalyseVO.LyFkybqkVO> result;

        switch (req.getType()) {
            case Constant.YEAR:
                lastDate = DateTime.of(date, YEAR_DATE_PATTERN).offset(DateField.YEAR, -1).toString(YEAR_DATE_PATTERN);
                //计算人均费用，和增幅，降幅
                result = lyFkybqkDao.queryDeptIndicatorAnalyseByYear(date, lastDate).stream().map(this::calScopeValue).collect(Collectors.toList());
                break;
            case Constant.MONTH:
                lastDate = DateTime.of(date, DatePattern.SIMPLE_MONTH_PATTERN).offset(DateField.MONTH, -1).toString(DatePattern.SIMPLE_MONTH_PATTERN);
                //计算人均费用，和增幅，降幅
                result = lyFkybqkDao.queryDeptIndicatorAnalyseByMon(date, lastDate).stream().map(this::calScopeValue).collect(Collectors.toList());
                break;
            default:
                return new DeptIndicatorAnalyseVO();
        }

        DeptIndicatorAnalyseVO vo = new DeptIndicatorAnalyseVO();
        vo.setIndicator(result);

        List<DeptIndicatorAnalyseVO.LyFkybqkVO> sorted = result.stream().sorted(Comparator.comparing(DeptIndicatorAnalyseVO.LyFkybqkVO::getScopeValue).reversed()).collect(Collectors.toList());

        //取top5, 并且去掉负增长的值
        List<DeptIndicatorAnalyseVO.LyFkybqkVO> increaseList = sorted.stream().limit(5).filter(lyFkybqkVO -> lyFkybqkVO.getScopeValue().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());

        vo.setIncrease(increaseList);

        if (CollUtil.isNotEmpty(sorted)) {
            //取倒数top5, 并且去掉正增长的值
            List<DeptIndicatorAnalyseVO.LyFkybqkVO> decreasingList = sorted.stream().skip(sorted.size() - 5)
                    .sorted(Comparator.comparing(DeptIndicatorAnalyseVO.LyFkybqkVO::getScopeValue)).filter(lyFkybqkVO -> lyFkybqkVO.getScopeValue().compareTo(BigDecimal.ZERO) < 0).collect(Collectors.toList());
            //重新排序
            vo.setDecreasing(decreasingList);
        } else {
            vo.setDecreasing(Lists.newArrayList());
        }
        return vo;
    }

    @Override
    public List<LyFkybqk> queryTop10DeptForInpatient(String startDate, String endDate, String dateType) {
        return lyFkybqkDao.queryTop10DeptForInpatient(startDate, endDate, dateType);
    }

    /**
     * 计算幅度
     *
     * @param lyFkybqk
     * @return
     */
    private DeptIndicatorAnalyseVO.LyFkybqkVO calScopeValue(LyFkybqk lyFkybqk) {
        DeptIndicatorAnalyseVO.LyFkybqkVO vo = new DeptIndicatorAnalyseVO.LyFkybqkVO();
        BeanUtil.copyProperties(lyFkybqk, vo);

        vo.setScopeFlag(vo.getInsuranceAmount() > vo.getLastInsuranceAmount());
        if (vo.getLastInsuranceAmount() == BigDecimal.ZERO.intValue()) {
            // 增幅100%
            vo.setScopeValue(BigDecimal.valueOf(100));
        } else {
            vo.setScopeValue(NumberUtil.round(NumberUtil.div(vo.getInsuranceAmount() - vo.getLastInsuranceAmount(), vo.getLastInsuranceAmount()) * 100, 2));
        }
        vo.setAvgInsuranceAmount(NumberUtil.div(lyFkybqk.getInsuranceAmount(), BigDecimal.valueOf(lyFkybqk.getPatientCount()), 2));
        vo.setLastAvgInsuranceAmount(lyFkybqk.getLastPatientCount() == 0
                ? BigDecimal.valueOf(100)
                : NumberUtil.div(lyFkybqk.getLastInsuranceAmount(), BigDecimal.valueOf(lyFkybqk.getLastPatientCount()), 2));
        return vo;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public LyFkybqk queryById(Long id) {
        return this.lyFkybqkDao.queryById(id);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<LyFkybqk> queryAllByLimit(int offset, int limit) {
        return this.lyFkybqkDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param lyFkybqk 实例对象
     * @return 实例对象
     */
    @Override
    public LyFkybqk insert(LyFkybqk lyFkybqk) {
        this.lyFkybqkDao.insert(lyFkybqk);
        return lyFkybqk;
    }

    /**
     * 修改数据
     *
     * @param lyFkybqk 实例对象
     * @return 实例对象
     */
    @Override
    public LyFkybqk update(LyFkybqk lyFkybqk) {
        this.lyFkybqkDao.update(lyFkybqk);
        return this.queryById(lyFkybqk.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        return this.lyFkybqkDao.deleteById(id) > 0;
    }
}